package algo3.juegoCarmenSanDiego.modelo;

import java.util.List;
import java.util.ArrayList;
import java.util.Random;

import algo3.juegoCarmenSanDiego.modelo.Ciudad;

public class Policia {
	private Rango rangoDePolicia;
	private Ciudad ciudadActual;
	private int tiempoRestante;
	private int casosGanados;
	private Boolean acaboElCasoParaElJugador;
	List <String> listaDeSospechosos=new ArrayList<String>();
	private boolean ordenValida;
	private String almacenDeMensaje;
	
	public Policia (Ciudad unaCiudad){
		this.ordenValida = false;
		this.rangoDePolicia = new Novato();
		this.ciudadActual=unaCiudad;
		this.acaboElCasoParaElJugador=false;
		this.casosGanados=0;
		this.tiempoRestante = 144;
	}
	public boolean tieneOrdenValida(){
		return this.ordenValida;
	}
	public int getVelocidad(){
		return rangoDePolicia.obtenerVelocidadApartirDelRango();
	};
	public void setCiudad(Ciudad unaCiudad){
		this.ciudadActual = unaCiudad;
	}
	public Boolean getOrdenDeArestoValida(){
		return this.ordenValida;
	}
	public Ciudad getCiudad(){
		return this.ciudadActual;
	}
	public void setRangoDePolicia(Rango rangoDePolicia) {
		this.rangoDePolicia = rangoDePolicia;
	}
	public Rango getRangoDePolicia() {
		return rangoDePolicia;
	}
	
	public String visitar(Edificio unEdificio){
		try {
			this.decrementarTiempo(unEdificio.obtenerTiempoQueTardaParaEntraraAunEdificio());
			return this.rangoDePolicia.buscarPistaEnEdificio(unEdificio);
		} catch (ExcepcionTiempo e) {
			this.acaboElCasoParaElJugador=true;
			return "";
		}	
	}
	public String visitar(TipoEdificioEnum unEdificio,Caso caso){
		Edificio edificio=this.ciudadActual.obtenerEdificio(unEdificio);
		try{
			this.decrementarTiempo(edificio.obtenerTiempoQueTardaParaEntraraAunEdificio());
			if (caso.esUltimaCiudad(this.ciudadActual.getNombreDeCiudad())){
				if(unEdificio==caso.edificioDeEsconditeDelLadron()){
					this.verSilaOrdenDeArrestoEsCorrecta(caso.getNombreDeLadron());
				}
				else{
					Random random = new Random();
					int numeroRandom = random.nextInt(2) + 1;
					switch ( numeroRandom ){
					case 1:
						this.recibirHeridaPorArmaDeFuego();
						break;
					case 2:
			           this.recibirHeridaPorCuhillo();
			           break;
					}	
				}
				return "";
			}
			else{
				this.decrementarTiempo(edificio.obtenerTiempoQueTardaParaEntraraAunEdificio());
				return this.rangoDePolicia.buscarPistaEnEdificio(edificio);
			}
		}
		catch(ExcepcionTiempo e){
			this.acaboElCasoParaElJugador=true;
			return "";
		}
		catch(ExcepcionOrdenArrestoEquivocada e){
			this.setAcaboElCasoParaElJugador(true);
			return "";
		}
		catch(ExcepcionCasoGanado e){
			this.acaboElCasoParaElJugador=true;
			this.casosGanados=(this.casosGanados)+1;
			return "";
		}
	}
	private void verSilaOrdenDeArrestoEsCorrecta(String unNombre) throws ExcepcionCasoGanado,ExcepcionOrdenArrestoEquivocada{
		Boolean sospechosoCorrecto=false;
		for(int i=0;i<=this.listaDeSospechosos.size()-1;i++){
			if(listaDeSospechosos.get(i).equals(unNombre)){
				sospechosoCorrecto=true;
			}	
		}
			if(sospechosoCorrecto){
				throw new ExcepcionCasoGanado();
			}	
			else{
				throw new ExcepcionOrdenArrestoEquivocada();
			}
	}
	public void setTiempoRestante(int tiempo){
		this.tiempoRestante = tiempo;
	}
	
	public int getTiempoRestante(){
		return this.tiempoRestante;
	}
	public void viajar (Ciudad ciudadDeDestino){
		try{
			int distancia = this.calcularDistanciaDeRecorridoDePolicia(this.ciudadActual,ciudadDeDestino);
			this.decrementarTiempo(calcularTiempoViajando(distancia, this.getVelocidad()));
			this.ciudadActual = ciudadDeDestino;
		}
		catch(ExcepcionTiempo e){
			this.acaboElCasoParaElJugador=true;
			this.almacenDeMensaje = "Se quedo sin tiempo";
		}
	}
	private int calcularTiempoViajando(int distancia, int velocidad) {
		return (distancia/velocidad);
	}
	
	private void decrementarTiempo(int tiempoADecrementar) throws ExcepcionTiempo{
		this.tiempoRestante = this.tiempoRestante - tiempoADecrementar;
		if (this.tiempoRestante <= 0)
			throw new ExcepcionTiempo();
	}
	
	private int calcularDistanciaDeRecorridoDePolicia(Ciudad ciudadDeOrigen, Ciudad ciudadDeDestino){
		
		int diferenciaHorizontal = ciudadDeDestino.getPosicionHorizontal() - ciudadDeOrigen.getPosicionHorizontal();
		int diferenciaVertical =  ciudadDeDestino.getPosicionVertical() - ciudadDeOrigen.getPosicionVertical();
		int productoEscalar = diferenciaHorizontal*diferenciaHorizontal + diferenciaVertical*diferenciaVertical;
		return (int) Math.sqrt(productoEscalar);
	}
	 void recibirHeridaPorArmaDeFuego() throws ExcepcionTiempo{
		int tiempoQueTardarEnRecuperarceDeLaHerida=4;
		this.decrementarTiempo(tiempoQueTardarEnRecuperarceDeLaHerida);
	}
	private void recibirHeridaPorCuhillo() throws ExcepcionTiempo {
		int tiempoQueTardarEnRecuperarceDeLaHerida=2;
		this.decrementarTiempo(tiempoQueTardarEnRecuperarceDeLaHerida);
	}
	public void emitirOrdenDeArresto(Interpol interpol,String unSexo,String unHobby,String unPelo,String unaSenia,String unCoche){
		try{
			this.decrementarTiempo(3);
			interpol.setSospechosoSexo(unSexo);
			interpol.setSospechosoHobby(unHobby);
			interpol.setSospechosoPelo(unPelo);
			interpol.setSospechosoSenia(unaSenia);
			interpol.setSospechosoCoche(unCoche);
			this.listaDeSospechosos=interpol.listaDeLadronesSospechosos();
		}
		catch(ExcepcionTiempo e){
			this.acaboElCasoParaElJugador=true;
		}
	}
	public void setCasosGanados(int casosGanados) {
		this.casosGanados = casosGanados;
	}
	public int getCasosGanados() {
		return this.casosGanados;
	}
	public void setAcaboElCasoParaElJugador(Boolean acaboElCasoParaElJugador) {
		this.acaboElCasoParaElJugador = acaboElCasoParaElJugador;
	}
	public Boolean getAcaboElCasoParaElJugador() {
		return acaboElCasoParaElJugador;
	}
	public List<String> getListaDeSospechosos(){
		return this.listaDeSospechosos;
	}
	public boolean emitirArresto(Interpol interpol) {
		try{
			this.decrementarTiempo(3);
			this.listaDeSospechosos=interpol.listaDeLadronesSospechosos();
			this.ordenValida = interpol.verificarOrdenArresto();
			return true;
		}
		catch(ExcepcionTiempo e){
			this.acaboElCasoParaElJugador=true;
			this.almacenDeMensaje = "Se quedo sin tiempo";
			return false;
		}
	}

	public boolean intentarAtraparLadron(TipoEdificioEnum unEdificio,TipoEdificioEnum edificioEscondite) {
		Edificio edificio = this.ciudadActual.obtenerEdificio(unEdificio);
		try {
			this.decrementarTiempo(edificio.obtenerTiempoQueTardaParaEntraraAunEdificio());
			if (unEdificio == edificioEscondite)
				if(this.ordenValida){
					this.almacenDeMensaje = "Gano el caso";
					this.casosGanados= (this.casosGanados)+1;
					return true;	
				}
				else{
					this.almacenDeMensaje = "Orden de Arresto Equivocada";
					return true;
				}
			else {
				
				Random random = new Random();
				int numeroRandom = random.nextInt(2) + 1;
				switch (numeroRandom) {
				case 1:
					this.recibirHeridaPorArmaDeFuego();
					this.almacenDeMensaje = "Policia recibio herida por arma de fuego. Intente en otro edificio";
					break;
				case 2:
					this.recibirHeridaPorCuhillo();
					this.almacenDeMensaje = "Policia recibio heria por cuchillo. Intente en otro edificio";
					break;
				}
			}
		}
		catch (ExcepcionTiempo e) {
			this.almacenDeMensaje = "Se quedo sin tiempo";
			this.acaboElCasoParaElJugador = true;
			return false;
		}
		return false;
	}
	public String getMensajeAcumulado(){
		return this.almacenDeMensaje;
	}
}	